#pragma once

#include <vector>
#include <queue>
#include "Cond.hpp"
#include "Mutex.hpp"
#include "Log.hpp"
#include "Thread.hpp"

namespace ThreadPoolModule
{
    using namespace ThreadModule;
    using namespace CondModule;
    using namespace MutexModule;
    using namespace LogModule;

    static const int gnum = 5; // 默认线程数

    template <typename T>
    class ThreadPool
    {
    public:
        // 构造函数
        ThreadPool(int num = gnum) : _num(num)
        {
            for (int i = 0; i < num; i++)
            {
                _threads.emplace_back(
                    [this]()
                    {
                        HandlerTask();
                    });
            }
        }

        // 线程启动
        void Start()
        {
            for (auto &t : _threads)
            {
                t.Start();
            }
        }

        // 线程处理函数
        void HandlerTask()
        {
            char name[128];
            pthread_getname_np(pthread_self(), name, sizeof(name));

            /*//打印日志
            while(1)
            {
                sleep(1);
                LOG(LogLevel::DEBUG) << "Thread: "<< name << " is running..." ;
            }*/

            // 处理任务
            while (1)
            {
                T t;
                {
                    LockGuard lockguard(_mutex);
                    while (_taskq.empty()) // 如果任务队列为空，则等待
                    {
                        _cond.Wait(_mutex);
                    }

                    // 取出任务
                    T task = _taskq.front();
                    _taskq.pop();
                }
                t(); // 执行任务
            }
        }

        // 析构函数
        ~ThreadPool()
        {
        }

    private:
        std::vector<Thread> _threads; // 线程池
        int _num;                     // 线程数量

        std::queue<T> _taskq; // 任务队列

        Cond _cond;   // 条件变量
        Mutex _mutex; // 互斥锁
    };

}